//
// Created by 廖海龙 on 2025/4/9.
//

#ifndef HELLOVIDEOCACHE_HELLOHTTPREQUEST_HPP
#define HELLOVIDEOCACHE_HELLOHTTPREQUEST_HPP

#include <string>
#include <unordered_map>
#include <regex>
#include <sstream>  // std::ostringstream
#include <iomanip>  // std::setw, std::setfill
#include <cctype>   // isalnum

#include "../cache/HelloRange.hpp"
#include "../log/Logger.hpp"


/**
 * Author: liaohailong
 * Date: 2025/4/9
 * Time: 14:34
 * Description:
 **/
class HelloHttpRequest
{
public:
    explicit HelloHttpRequest(int connFd, const std::string &text);

    ~HelloHttpRequest();

public:
    [[nodiscard]] int getConnFd() const noexcept;

    std::shared_ptr<HelloRange> getRange();

    std::string getRealUrl();

    bool getQueryParams(std::unordered_map<std::string, std::string> &query);

    void setWrite2Cache(bool write2cache);

    /**
     * @return 本次客户端的请求，是否需要将网络数据缓存至本地
     */
    [[nodiscard]] bool isWrite2Cache() const;

    /**
     * @param writeHeader 是否需要写 HTTP 响应头，协议状态码+首部字段
     */
    void markHeaderWriten();

    [[nodiscard]] bool needWriteHeader() const;

private:
    void read(const std::string &text);

public:
    static std::string urlDecode(const std::string &in);

    static std::string urlEncode(const std::string &in);

private:
    Logger logger;
    std::string method;
    std::string path;
    std::string version;

    std::unordered_map<std::string, std::string> headers;

    /**
     * 客户端连接 socket fd
     */
    int connFd;

    /**
     * 本次客户端的请求，是否需要将网络数据缓存至本地
     */
    bool write2cache;

    /**
     * 标记 HTTP 响应头，协议状态码+首部字段 是否已经写过了
     */
    bool headerWriten;
};


#endif //HELLOVIDEOCACHE_HELLOHTTPREQUEST_HPP
